<template>
    <!-- 主页 -->
    <div class="home-home oct-primary-background-color sept-cursor-default">
        <div class="home-home">
            <a
                v-show="false"
                ref="aButton"
                :href="aUrl + `?__unique=${new Date().getTime()}`"
                target="_blank"
            ></a>
            <!-- 左侧菜单区域 :ignore="true"-->
            <div class="home-home-left">
                <SeptMenu
                    :data="menus"
                    :ignore="true"
                    @exe-click="ExeMenuClick"
                    @exe-transitionend="Transitionend"
                    titlename="测试"
                    logo=""
                ></SeptMenu>
            </div>
            <!-- 右侧内容区域 -->
            <div class="home-home-right">
                <!-- 皮肤、消息、设置、用户 -->
                <div class="home-head-right">
                    <SeptHeader
                        class="home-header"
                        :skins="data.skins"
                        :username="info.orguser_cn_name"
                        @exe-signout="ExeSignout"
                        search
                        :infos="info"
                        :keies="keies"
                        @exe-explore="ExeExplore"
                        :abandon="abandon"
                        :total="messages.total"
                        :unreadtotal="messages.unreadtotal"
                        :messages="messages.data"
                        @exe-page="ExeGetMessagesQueue"
                        @exe-signread="ExePutMessagesState"
                        @exe-delete="ExeDeteleMessage"
                        :portrait="require('@/assets/image/user.png')"
                    ></SeptHeader>
                </div>
                <!-- 头部导航区 -->
                <div class="home-home-head oct-box-shadow">
                    <!-- TAB页签 -->
                    <div class="home-head-center">
                        <SeptRoster
                            :data="tabs"
                            @exe-click="ExeTabClick"
                            @exe-remove="ExeTabRemove"
                            @exe-closeall="ExeCloseAll"
                            :reload="roster"
                        ></SeptRoster>
                    </div>
                </div>
                <!-- 主面板区 -->
                <div class="home-home-body">
                    <div class="home-home-body-header">
                        <SeptBreadcrumb
                            v-if="breadcrumbData.length"
                            class="home-home-body-breadcrumb"
                            :separator="separator"
                        >
                            <SeptBreadcrumb-item
                                v-for="(item, index) in breadcrumbData"
                                :key="index"
                                :to="
                                    item.meta && !item.meta.isActive
                                        ? item.name
                                        : ''
                                "
                                ><i
                                    v-if="!index"
                                    class="september sept-icon-factory"
                                ></i
                                >{{ item.title }}</SeptBreadcrumb-item
                            >
                        </SeptBreadcrumb>
                    </div>
                    <keep-alive :include="alives.join(',')">
                        <router-view
                            v-if="precondition && $route.meta.keepAlive == true"
                        />
                    </keep-alive>
                    <router-view
                        v-if="precondition && $route.meta.keepAlive == false"
                    />
                </div>
            </div>
            <!-- 全局内容 -->
            <input class="copy-input" type="text" id="_copyInput" />
            <SeptLoading
                id="__loading"
                style="visibility: hidden"
            ></SeptLoading>
        </div>
    </div>
</template>

<script>
import { mapActions } from "vuex";
import Initialize from "sept-ui/lib/utils/builtin/initialize";
import theme from "@/library/theme.json";
import { Result } from "../utils/communicate/result.dispose";
export default {
    provide() {
        return {
            reload: this.reload
        };
    },
    data() {
        return {
            aUrl: window.__GlobalConfig.userCenter,
            roster: true, //花名册重新渲染标识
            precondition: false, //前置条件，当前置条件满足后再渲染页面，保证数据存在
            data: {
                skins: [],
                menus: []
            },
            tabs: [
                {
                    label: "项目管理",
                    path: "projectManage",
                    code: "AT010102",
                    active: true,
                    firm: true
                }
            ], //储存在session
            menus: [],
            alives: ["65535"], //keepalive缓存的页面，要求组件的name属性和router中的path一致（需要至少有一个对象）
            nowRouteName: {}, //当前路由信息
            breadcrumbData: [], //面包屑导航数据
            projectData: [],
            info: {}, //用户信息
            keies: [], //搜索列表
            abandon: [1, 0, 3],
            messages: {
                data: [],
                total: 0,
                unreadtotal: 0,
                start: 0
            },
            separator: "/"
        };
    },

    created() {
        //初始化全局参数仓库&&皮肤初始化
        if (!this.$store.__configs) Initialize.HomeInitialize(this, theme);
        //获取菜单资源
        this.ExeGetMenus();
        let cd = this.$_T.GetSessionStorage("CommData");
        this.info = JSON.parse(cd);
        this.ExeGetMessagesQueue();
        this.UnreadMessagesQueue();
    },

    mounted() {
        let code = this.$_T.GetSessionStorage("__code");
        //在不切换系统的前提下
        if (!code || code == window.__GlobalConfig.rsCode) {
            this.$_T.SetSessionStorage("__code", window.__GlobalConfig.rsCode);
            //页面刷新时获取session中存储的tabs
            let tabs = this.$_T.GetSessionStorage("__tabs");
            if (tabs) {
                this.tabs = JSON.parse(tabs);
            }
        } else {
            this.$_T.SetSessionStorage("__code", window.__GlobalConfig.rsCode);
        }
        this.$nextTick(() => {
            this.reload();
            let code = "";
            this.tabs.forEach(tab => {
                if (tab.active) code = tab.code;
            });
            //更新菜单状态
            this.ResetSpread(this.menus);
            this.SetMenuByTab(this.menus, code);
        });
    },

    watch: {
        $route: function(to) {
            this.CheckTab(to);
        }
    },

    methods: {
        Transitionend() {
            this.roster = !this.roster;
        },
        CheckTab(to, co) {
            //缓存alives
            if (!to.meta.keepAlive) {
                //当跳转的路由不需要缓存时，清除
                //移除对应组件（页面）的keepalive缓存
                for (let i = 0; i < this.alives.length; i++) {
                    if (this.alives[i] == to.name.toLowerCase()) {
                        this.alives.splice(i, 1);
                        return;
                    }
                }
            } else {
                //添加需要缓存的路由
                if (this.alives.indexOf(to.name.toLowerCase()) == -1) {
                    this.alives.push(to.name.toLowerCase());
                }
            }
            //当通过非导航跳转时，需要主动更新视图（兼容tabs中可能存在也可能不存在）
            if (this.$route.query.code || co) {
                //更新菜单视图
                this.ResetSpread(this.menus);
                this.SetMenuByTab(this.menus, to.query.code || co);
                //更新session中的tabs（激活状态）
                this.$_T.SetSessionStorage("__tabs", JSON.stringify(this.tabs));
            }
            //添加到tabs（兼容非菜单的跳转）
            if (!to.query.code && !co) return;
            let flag = this.tabs.some(tab => {
                return (
                    tab.path.replace(/\//, "").toLowerCase() ==
                    to.name.toLowerCase()
                );
            });
            //添加到tabs
            if (!flag) {
                //不存在
                this.tabs.forEach(tab => {
                    tab.active = false;
                });
                this.tabs.push({
                    label: to.meta.title,
                    path: to.path,
                    code: to.query.code || co,
                    active: true,
                    query: {}
                });
            } else {
                //已存在
                this.tabs.forEach(tab => {
                    if (tab.code == (to.query.code || co)) {
                        tab.active = true;
                    } else {
                        tab.active = false;
                    }
                });
            }
        },
        ExeExplore(it) {
            if (!it) return;
            this.ExeMenuClick(it);
            this.ExeTabClick(it);
        },
        //构造搜索菜单列表
        AssemblyMenuList(menu) {
            this.keies = [];
            let _this = this;
            loop(menu);
            function loop(item) {
                item.forEach(it => {
                    let op = { ...it };
                    op.label = op.name;
                    _this.keies.push(op);
                    if (it.subs) {
                        loop(it.subs);
                    }
                });
            }
        },
        reload() {
            this.precondition = false;
            this.$nextTick(function() {
                this.precondition = true;
            });
        },
        /**
         * 重组菜单
         */
        AssembleMenus(source, target) {
            for (let i = 0; i < source.length; i++) {
                let obj = {
                    code: source[i].rs_code,
                    path: source[i].frame,
                    name: source[i].name || source[i].text,
                    icon: source[i].rsim_url,
                    spread: false
                };
                if (source[i].tabs) {
                    obj.subs = [];
                    this.AssembleMenus(source[i].tabs, obj.subs);
                }
                target.push(obj);
            }
        },
        //点击tab
        ExeTabClick(item) {
            this.ResetSpread(this.menus);
            this.SetMenuByTab(this.menus, item.code);
            this.$router.push({ path: item.path, query: item.query });
            //更新session中的tabs（激活状态）
            this.$_T.SetSessionStorage("__tabs", JSON.stringify(this.tabs));
        },
        //移除tab
        ExeTabRemove(a, b) {
            //当存在b时，表移除的tab是激活的标签，需要激活新的标签，即b
            if (b) {
                this.ResetSpread(this.menus);
                this.SetMenuByTab(this.menus, b.code);
                this.$router.push({ path: b.path, query: b.query });
            }
            //更新session中的tabs（此时的tabs在组件内已经处理过了）
            this.$_T.SetSessionStorage("__tabs", JSON.stringify(this.tabs));
            //移除对应组件（页面）的keepalive缓存
            for (let i = 0; i < this.alives.length; i++) {
                if (this.alives[i] == a.path.toLowerCase()) {
                    this.alives.splice(i, 1);
                    return;
                }
            }
            //移除对应组件（页面）的keepalive缓存
            for (let i = 0; i < this.alives.length; i++) {
                if (this.alives[i] == a.path.toLowerCase()) {
                    this.alives.splice(i, 1);
                    return;
                }
            }
        },
        //关闭全部标签（固定除外）
        ExeCloseAll(a, b) {
            //更新session中的tabs（激活状态）
            this.$_T.SetSessionStorage("__tabs", JSON.stringify(this.tabs));
            //当存在b时，表移除的tab包括激活的标签，需要激活新的标签，即b
            if (b) {
                this.ResetSpread(this.menus);
                this.SetMenuByTab(this.menus, b.code);
                this.$router.push({ path: b.path, query: b.query });
            }
            //清除多余keepalive缓存
            this.alives = ["65535"];
            a.forEach(ele => {
                this.alives.push(ele.path);
            });
        },
        //重置菜单状态
        ResetSpread(item) {
            item.forEach(it => {
                it.spread = false;
                if (it.subs) {
                    this.ResetSpread(it.subs);
                }
            });
        },
        //点击tab后找到菜单中对应的数据
        SetMenuByTab(item, code) {
            for (let i = 0; i < item.length; i++) {
                if (item[i].code == code) {
                    item[i].spread = true;
                    if (code.length == 2) {
                        return;
                    }
                    //向上寻根
                    this.FindItemByCode(
                        item[i].code.substr(0, item[i].code.length - 2)
                    );
                    return;
                    //判断是否是根一族
                } else if (new RegExp(`^(${item[i].code})`).test(code)) {
                    this.SetMenuByTab(item[i].subs, code);
                    return;
                }
            }
        },
        //根据code查找子菜单族
        FindItemByCode(code, list) {
            let m = list ? list : this.menus,
                c = code;
            for (let i = 0; i < m.length; i++) {
                //判断是否是根一族
                if (new RegExp(`^(${m[i].code})`).test(code)) {
                    m[i].spread = true;
                    if (code == m[i].code) return;
                    this.FindItemByCode(code, m[i].subs);
                    return;
                }
            }
        },
        //点击菜单
        ExeMenuClick(item) {
            //以下为点击子菜单后对tabs的影响
            //判断tabs中是否以存在该标签
            let flag = this.tabs.some(it => {
                return it.code === item.code;
            });
            if (!flag) {
                this.tabs.push({
                    label: item.name,
                    path: item.path,
                    code: item.code,
                    active: false,
                    query: {}
                });
                //添加对应组件（页面）的keepalive缓存
                this.alives.push(item.path.toLowerCase());
            }
            this.tabs.forEach(it => {
                it.active = false;
                if (it.label == item.name) {
                    it.active = true;
                }
            });
            //更新session中的tabs
            this.$_T.SetSessionStorage("__tabs", JSON.stringify(this.tabs));
        },
        FindCodeByName(name, menus) {
            for (let i = 0; i < menus.length; i++) {
                if (menus[i].name == name) {
                    return menus[i].code;
                } else if (menus[i].subs) {
                    let code = this.FindCodeByName(name, menus[i].subs);
                    if (code) {
                        return code;
                    }
                }
            }
        },
        ...mapActions([
            "Signout",
            "GetMenus",
            "GetMessagesQueue",
            "PutMessagesState",
            "DeteleMessage"
        ]),
        //获取菜单资源
        ExeGetMenus() {
            let param = { bl_rs_code: window.__GlobalConfig.rsCode };
            let _this = this;
            function Callback(res) {
                _this.menus = [];
                _this.AssembleMenus(
                    res.data.level_menu_list[0].meun_bean_list,
                    _this.menus
                );
                //储存菜单
                _this.$_T.SetSessionStorage(
                    "__menu",
                    JSON.stringify(_this.menus)
                );
                _this.AssemblyMenuList(_this.menus);
                //当项目中有固定菜单时，更新菜单状态
                let code = "";
                _this.tabs.forEach(tab => {
                    if (tab.active) code = tab.code;
                });
                _this.ResetSpread(_this.menus);
                _this.SetMenuByTab(_this.menus, code);

                //统一登录后定位菜单和tab
                if (localStorage.getItem("__jwt")) {
                    //获取菜单对应的code
                    let co = _this.FindCodeByName(
                        _this.$route.meta.title,
                        _this.menus
                    );
                    _this.CheckTab(_this.$route, co);
                }

                Callback = null;
            }
            Result(this, "GetMenus", param, Callback, false);
        },
        //退出
        ExeSignout() {
            let _this = this;
            localStorage.clear();
            function Callback() {
                let __theme = _this.$_T.GetSessionStorage("__theme");
                _this.$_T.ClearSessionStorage();
                //当皮肤没有更改过时，相当于第一次访问，不需要保存
                if (__theme) {
                    _this.$_T.SetSessionStorage("__theme", __theme);
                }
                _this.$router.push({ path: "Login" });
                _this.$store.__configs = null; //当退出登录后，store并不会清空，导致再登录不会触发皮肤加载函数，故此特意清空该数据
                let exdate = new Date();
                exdate.setDate(exdate.getDate() - 1);
                document.cookie = `jwt='0'; expires=${exdate.toGMTString()}; path=/`;
                document.cookie = "jwt=0; expires=" + new Date(0).toUTCString();
                location.reload(); //清除除了theme的其他存储参数
                Callback = null;
            }
            Result(this, "Signout", {}, Callback, false);
        },
        ExeGetMessagesQueue(start) {
            if (start) this.messages.start = start;
            let param = {
                limit_recd: 10,
                start_recd: this.messages.start
            };
            let _this = this;
            function Callback(res) {
                _this.messages.total = res.data.all_recd;
                _this.messages.data = res.data.msg_list || [];
                _this.messages.data.forEach(ele => {
                    ele.label = ele.msg_title;
                    ele.state = ele.rc_flag;
                    _this.$set(ele, "checked", false);
                });
                Callback = null;
            }
            Result(this, "GetMessagesQueue", param, Callback, false);
        },
        UnreadMessagesQueue() {
            let param = {
                limit_recd: 10,
                start_recd: 0,
                rc_flag: 2
            };
            let _this = this;
            function Callback(res) {
                _this.messages.unreadtotal = res.data.all_recd;
                Callback = null;
            }
            Result(this, "GetMessagesQueue", param, Callback, false);
        },
        ExePutMessagesState(item) {
            let _this = this;
            let param = {
                work_seq_array: []
            };
            if (item) {
                param.work_seq_array.push(item.work_seq);
            } else {
                _this.messages.data.forEach(ele => {
                    if (ele.checked) param.work_seq_array.push(ele.work_seq);
                });
            }
            function Callback(res) {
                _this.ExeGetMessagesQueue();
                _this.UnreadMessagesQueue();
                Callback = null;
            }
            Result(this, "PutMessagesState", param, Callback, false);
        },
        ExeDeteleMessage() {
            let param = {
                work_seq_array: []
            };
            this.messages.data.forEach(ele => {
                if (ele.checked) param.work_seq_array.push(ele.work_seq);
            });
            let _this = this;
            function Callback(res) {
                _this.ExeGetMessagesQueue();
                _this.UnreadMessagesQueue();
                Callback = null;
            }
            Result(this, "DeteleMessage", param, Callback, false);
        }
    }
};
</script>
<style lang="less">
.sept-menu-subitem > div {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.sept-header-operation {
    .sept-input-key-list {
        .sept-cursor-pointer {
            text-align: left;
        }
    }
}
.sept-ma-content {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    div[name="content"] {
        flex: 1;
        overflow: auto;
    }
}
.sept-mq-box {
    z-index: 100000000;
}
</style>
<style lang="less" scoped>
@height: 56px;
@headerwidth: 465px;
.home-home {
    width: 100%;
    height: 100%;
    overflow: hidden;
    position: relative;
    display: flex;
    &-left {
        height: 100%;
        position: relative;
    }
    &-right {
        flex: 1;
        height: 100%;
        overflow: hidden;
        position: relative;
        .home-head-right {
            height: @height;

            position: absolute;
            right: 20px;
            top: 5px;
            width: @headerwidth;
            z-index: 1;
        }
        .home-home-head {
            height: @height;
            box-sizing: border-box;
            padding: 5px 10px 3px 10px;
            position: relative;
            width: 100%;
            .home-head-center {
                height: 100%;
                width: calc(100% - @headerwidth - 20px);
                position: relative;
            }
        }
        .home-home-body {
            height: calc(100% - @height);
            padding: 12px;
            position: relative;
            overflow: hidden;
            display: flex;
            flex-direction: column;
            .home-home-body-main {
                height: calc(100% - 28px);
            }
            .home-home-body-breadcrumb {
                height: 20px;
                display: inline-block;
                margin-left: -15px;
                margin-bottom: 8px;
            }
            .home-home-body-project {
                position: absolute;
                right: 10px;
                top: 10px;
                z-index: 12;
            }
        }
    }
    .copy-input {
        position: absolute;
        top: 0;
        opacity: 0;
        pointer-events: none;
    }
}
.full-display {
    opacity: 0;
}
</style>
